home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / support / timefix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-01-23  |  7.3 KB  |  485 lines

  1. # include    <fcntl.h>
  2. # include    <sccs.h>
  3.  
  4. SCCSID(@(#)timefix.c    8.2    1/18/85)
  5.  
  6. /*
  7. ** TIMEFIX -- patch binary program to correct for timezone changes.
  8. **
  9. **    Timefix is compiled with the ctime(III) variables:
  10. **        daylight,
  11. **        timezone,
  12. **        tzname[]
  13. **
  14. **    Each file specified is examined to see if it contains
  15. **    all of these variables. If it does then the current values
  16. **    of those variables for that file are given. If the "-u" flag
  17. **    is specified then the values are not overwritten.
  18. **
  19. **    The other flags can be used to override the values of the
  20. **    variables; specifically:
  21. **        -sxxx  --> timezone    (xxx converted from ascii to binary)
  22. **        -dx    --> daylight    (x converted from ascii to binary)
  23. **        -tXXXYYY -> tzname[0] = "XXX" and tzname[1] = "YYY"
  24. */
  25.  
  26. struct header
  27. {
  28.     int    magic;
  29.     int    tsize;
  30.     int    dsize;
  31.     int    bss;
  32.     int    ssize;
  33.     int    start_ad;
  34.     int    unused;
  35.     int    reloc_flag;
  36. };
  37.  
  38. struct sym
  39. {
  40.     char    symname[8];
  41.     int    type;
  42.     int    value;
  43. };
  44.  
  45.  
  46. /* these values are defined in the unix ctime() routine */
  47. extern int    daylight;
  48. extern int    timezone;
  49. extern char    *tzname[];
  50.  
  51. int    Noupdate;
  52.  
  53. main(argc, argv)
  54. int    argc;
  55. char    *argv[];
  56. {
  57.  
  58.     if (argc < 2)
  59.     {
  60.         printf("usage: timefix filename ...\n");
  61.         exit (1);
  62.     }
  63.  
  64.     argc--;
  65.     argv++;
  66.  
  67.     if (checkflags(&argc, argv))
  68.         exit (1);
  69.  
  70.     pr_values("your installation", timezone, tzname[0], tzname[1], daylight);
  71.  
  72.     while (argc--)
  73.         newtime(*argv++);
  74. }
  75. /*
  76. **  NEWTIME
  77. */
  78.  
  79. newtime(filename)
  80. char    *filename;
  81. {
  82.     struct sym    timez, name_st, name_dy, dayflag;
  83.     struct header    head;
  84.     register int    i, fdes;
  85.     int        adr, secs;
  86.     char        std[4], dyl[4];
  87.  
  88.     if ((fdes = openheader(&head, filename)) < 0)
  89.         return (-1);
  90.  
  91.     bmove("_timezon", timez.symname, 8);
  92.     bmove("_tzname\0", name_st.symname, 8);
  93.     bmove("_dayligh", dayflag.symname, 8);
  94.  
  95.     /* pick up addresses from symbol table */
  96.     i = findsymbol(&head, fdes, &timez);
  97.     i |= findsymbol(&head, fdes, &name_st);
  98.     i |= findsymbol(&head, fdes, &dayflag);
  99.  
  100.     if (i)
  101.     {
  102.         printf("File %s does not need to be corrected\n", filename);
  103.         close(fdes);
  104.         return (-2);
  105.     }
  106.  
  107.     /* form entries for pointer to "PST" and "PDT" */
  108.     i = getvalue(&head, fdes, &name_st, &adr, 2);
  109.     name_st.value += 2;
  110.     i |= getvalue(&head, fdes, &name_st, &name_dy.value, 2);
  111.     name_dy.type = name_st.type;
  112.     name_st.value = adr;
  113.  
  114.     if (i)
  115.     {
  116.         printf("can't find pointers to timezone names in %s\n", filename);
  117.         close(fdes);
  118.         return (-3);
  119.     }
  120.  
  121.     /* now print out current values */
  122.     i = getvalue(&head, fdes, &timez, &secs, 2);
  123.     i |= getvalue(&head, fdes, &name_st, std, 4);
  124.     i |= getvalue(&head, fdes, &name_dy, dyl, 4);
  125.     i |= getvalue(&head, fdes, &dayflag, &adr, 2);
  126.  
  127.     if (i)
  128.     {
  129.         printf("one or more symbols cannot be read from %s\n", filename);
  130.         close(fdes);
  131.         return (-4);
  132.     }
  133.  
  134.     pr_values(filename, secs, std, dyl, adr);
  135.  
  136.     if (!Noupdate)
  137.     {
  138.         if (putvalue(&head, fdes, &timez, &timezone, 2)
  139.             || putvalue(&head, fdes, &name_st, tzname[0], 4)
  140.             || putvalue(&head, fdes, &name_dy, tzname[1], 4)
  141.             || putvalue(&head, fdes, &dayflag, &daylight, 2))
  142.         {
  143.             printf("cannot update %s with new values\n", filename);
  144.             close(fdes);
  145.             return (-2);
  146.         }
  147.         else
  148.             printf("File %s updated.\n", filename);
  149.     }
  150.  
  151.  
  152.     close(fdes);
  153.  
  154.     return (0);
  155. }
  156. /*
  157. **    Open the indicated file and read & verify header
  158. */
  159.  
  160. openheader(hd, filename)
  161. struct header    *hd;
  162. char        *filename;
  163. {
  164.     register int    fd, i;
  165.  
  166.     if ((fd = open(filename, O_RDWR)) < 0)
  167.     {
  168.         printf("can't open file %s\n", filename);
  169.         return (-1);
  170.     }
  171.  
  172.     if ((i = read(fd, hd, sizeof (*hd))) != sizeof (*hd))
  173.     {
  174.         printf("can't read in header\n");
  175.         close(fd);
  176.         return  (-2);
  177.     }
  178.  
  179.     switch (hd->magic)
  180.     {
  181.  
  182.       case 0407:
  183.       case 0410:
  184.       case 0411:
  185.         if (hd->ssize)
  186.             break;
  187.         printf("File %s does not have a symbol table.\n", filename);
  188.         return (-4);
  189.  
  190.       default:
  191.         printf("%s not an object file\n", filename);
  192.         return (-3);
  193.     }
  194.  
  195.     return (fd);
  196. }
  197. /*
  198. **    Seek to beginning of symbol table
  199. */
  200.  
  201. startsymbol(hd, fdx)
  202. struct header    *hd;
  203. int        fdx;
  204. {
  205.     register int        i, fd;
  206.     register struct header    *h;
  207.     long            offset;
  208.     long            itol();
  209.  
  210.     h = hd;
  211.     fd = fdx;
  212.  
  213.     /* seek past header */
  214.     i = lseek(fd, 16L, 0);
  215.  
  216.     /* seek to start of symbol table */
  217.     offset = itol(h->tsize);
  218.     offset = offset + itol(h->dsize);
  219.     if (h->reloc_flag == 0)
  220.         offset += offset;
  221.  
  222.     i |= lseek(fd, offset, 1);
  223.  
  224.     if (i < 0)
  225.     {
  226.         printf("can't seek to symbol table\n");
  227.         return (-1);
  228.     }
  229.  
  230.     return (0);
  231. }
  232. /*
  233. **    Locate symbol in symbol table and return sucess-failure
  234. */
  235.  
  236. findsymbol(hd, fd, s)
  237. struct header    *hd;
  238. int        fd;
  239. struct sym    *s;
  240. {
  241.     register int    i, j;
  242.     struct sym    next;
  243.  
  244.     if (startsymbol(hd, fd))
  245.         return (-1);
  246.  
  247.     for (i = hd->ssize; i--; )
  248.     {
  249.         j = read(fd, &next, sizeof (next));
  250.  
  251.         if (j != sizeof (next))
  252.         {
  253.             if (j)
  254.                 printf("symbol table error %d,%d,%d\n", hd->ssize, i, j);
  255.             return (-1);
  256.         }
  257.  
  258.         if (bequal(next.symname, s->symname, sizeof (next.symname)))
  259.         {
  260.             s->type = next.type;
  261.             s->value = next.value;
  262.             return (0);
  263.         }
  264.     }
  265.  
  266.     return (1);
  267. }
  268. /*
  269. **  GETVALUE
  270. */
  271.  
  272. getvalue(hd, fd, s, cp, len)
  273. struct header    *hd;
  274. int        fd;
  275. struct sym    *s;
  276. char        *cp;
  277. int        len;
  278. {
  279.     register int    i;
  280.     long        getaddr(), addr;
  281.  
  282.     addr = getaddr(hd, s);
  283.     if (addr == -1)
  284.         return (-1);
  285.  
  286.     if (lseek(fd, addr, 0) < 0)
  287.         return (-1);
  288.  
  289.     if ((i = read(fd, cp, len)) != len)
  290.         return (-1);
  291.  
  292.     return (0);
  293. }
  294. /*
  295. **  PUTVALUE
  296. */
  297.  
  298.  
  299. putvalue(hd, fd, s, loc, len)
  300. struct header    *hd;
  301. int        fd;
  302. struct sym    *s;
  303. char        *loc;
  304. int        len;
  305. {
  306.     long        adr, getaddr();
  307.  
  308.     adr = getaddr(hd, s);
  309.     if (adr == -1)
  310.         return (-1);
  311.  
  312.     if (lseek(fd, adr, 0) < 0)
  313.         return (-1);
  314.  
  315.     if (write(fd, loc, len) != len)
  316.         return (-2);
  317.  
  318.     return (0);
  319. }
  320. /*
  321. **  PR_VALUES
  322. */
  323.  
  324. pr_values(str, secs, std, dyl, flag)
  325. char    *str;
  326. int    secs;
  327. char    *std;
  328. char    *dyl;
  329. int    flag;
  330. {
  331.     printf("\nCurrent values for %s are:\n\t# seconds past greenwich:  %d\n", str, secs);
  332.     printf("\ttimezones:  %.4s and %.4s\n\tdaylight saving flag:  %d\n", std, dyl, flag);
  333. }
  334. /*
  335. **  CHECKFLAGS
  336. */
  337.  
  338. checkflags(argc, argv)
  339. int    *argc;
  340. char    *argv[];
  341. {
  342.     register char    *cp, **nargv;
  343.     register int    cnt;
  344.     int        ret;
  345.  
  346.     ret = 0;
  347.     cnt = *argc;
  348.     nargv = argv;
  349.     while (cnt--)
  350.     {
  351.         cp = *argv++;
  352.         if (*cp == '-')
  353.         {
  354.             (*argc)--;
  355.             cp++;
  356.             switch (*cp++)
  357.             {
  358.  
  359.               case 's':
  360.                 timezone = atoi(cp);
  361.                 break;
  362.  
  363.               case 't':
  364.                 bmove(cp, tzname[0], 3);
  365.                 bmove(cp+3, tzname[1], 3);
  366.                 break;
  367.  
  368.               case 'd':
  369.                 daylight = atoi(cp);
  370.                 break;
  371.  
  372.               case 'u':
  373.                 Noupdate++;
  374.                 break;
  375.  
  376.               default:
  377.                 printf("bad flag %s\n", cp - 2);
  378.                 ret = -1;
  379.             }
  380.         }
  381.         else
  382.             *nargv++ = cp;
  383.     }
  384.  
  385.     return (ret);
  386. }
  387.  
  388.  
  389. bmove(src, dst, len)
  390. char    *src;
  391. char    *dst;
  392. int    len;
  393. {
  394.     register int    i;
  395.     register char    *s, *d;
  396.  
  397.     s = src;
  398.     d = dst;
  399.     i = len;
  400.  
  401.     while (i--)
  402.         *d++ = *s++;
  403. }
  404.  
  405.  
  406. bequal(s1, s2, len)
  407. char    *s1;
  408. char    *s2;
  409. int    len;
  410. {
  411.     register int    i;
  412.     register char    *s, *d;
  413.  
  414.     s = s1;
  415.     d = s2;
  416.     i = len;
  417.  
  418.     while (i--)
  419.         if (*s++ != *d++)
  420.             return (0);
  421.  
  422.     return (1);
  423. }
  424. /*
  425. **  GETADDR
  426. */
  427.  
  428. long
  429. getaddr(hd, s)
  430. struct header    *hd;
  431. struct sym    *s;
  432. {
  433.     long    addr;
  434.     int    i;
  435.     long    l;
  436.     long    itol();
  437.  
  438.     addr = s->value + 16;    /* offset past header */
  439.  
  440.     switch (s->type)
  441.     {
  442.  
  443.       /* extern text segment */
  444.       case 042:
  445.         return (addr);
  446.  
  447.       /* data segment extern */
  448.       case 043:
  449.         switch (hd->magic)
  450.         {
  451.  
  452.           case 0407:
  453.             return (addr);
  454.  
  455.           case 0410:
  456.             /* subtract space between text and data */
  457.             l = itol(hd->tsize) + 017777;
  458.             l &= ~017777;
  459.  
  460.             return (addr - (l - itol(hd->tsize)));
  461.  
  462.           case 0411:
  463.             return (addr + itol(hd->tsize));
  464.  
  465.         }
  466.       default:
  467.         printf("Invalid symbol type %o\n", s->type);
  468.         return (-1);
  469.     }
  470. }
  471.  
  472.  
  473. long itol(value)
  474. int    value;
  475. {
  476.     long    ret;
  477.     int    *ip;
  478.  
  479.     ret = value;
  480.     ip = &ret;
  481.     *ip = 0;
  482.  
  483.     return (ret);
  484. }
  485.